package com.myplans.client.presenter;

import java.util.ArrayList;
import java.util.List;

import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.shared.GwtEvent;
import com.google.gwt.event.shared.HandlerManager;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.FileUpload;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.FormPanel;
import com.google.gwt.user.client.ui.FormPanel.SubmitCompleteEvent;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.Hyperlink;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Widget;
import com.myplans.client.Presenter;
import com.myplans.client.UserUtil;
import com.myplans.client.event.UpdateUserEvent;
import com.myplans.client.event.ViewPlanEvent;
import com.myplans.client.presenter.HomePresenter.Display;
import com.myplans.client.service.PlanServiceAsync;
import com.myplans.client.service.UserServiceAsync;
import com.myplans.client.view.BaseView;
import com.myplans.client.view.HomeView;
import com.myplans.client.view.SettingsView;
import com.myplans.client.view.custom.PlanPanel;
import com.myplans.shared.Plan;
import com.myplans.shared.User;


public class ProfilePresenter implements Presenter {

	public interface SettingsDisplay {

		public Widget asWidget();
		
		public Button getSave();

		public String getName();

		public String getUsername();

		public String getEmail();
		
		public void setName(String name);

		public void setUsername(String username);

		public void setEmail(String email);
		
		public FormPanel getAddPictureForm();

		public FileUpload getPictureUpload();

		public Image getPicture();
		
		public void setPicture(Image image);
		
	}
	
	public interface ProfileDisplay {
		
		public Widget asWidget();
		
		public Hyperlink getMyplans();

		public Hyperlink getNotifications();

		public Hyperlink getSettings();

		public FlowPanel getRightPanel();
		
	}

	private HandlerManager eventBus;
	private SettingsDisplay settingsDisplay;
	private ProfileDisplay profileDisplay;
	private final Display planDisplay;
	private UserServiceAsync userServiceAsync;
	private PlanServiceAsync planService;
	private List<Hyperlink> categoriesHyperlinks = new ArrayList<Hyperlink>();

	public ProfilePresenter(HandlerManager eventBus, ProfileDisplay display) {
		this.eventBus = eventBus;
		this.settingsDisplay = new SettingsView();
		this.planDisplay = new HomeView();
		this.profileDisplay = display;
		this.bind();
	}

	public void go(HasWidgets container) {
		((BaseView)container).getCentralPanel().clear();
//		profileDisplay.getRightPanel().clear();
//		profileDisplay.getRightPanel().add(settingsDisplay.asWidget());
		((BaseView)container).getCentralPanel().add(profileDisplay.asWidget());
		
		settingsDisplay.setName(UserUtil.user.getName());
		if (UserUtil.user.getUsername() != null) {
			settingsDisplay.setUsername(UserUtil.user.getUsername());
		}
		if (UserUtil.user.getPicture() != null) {
			Image image = new Image(UserUtil.user.getPicture());
			image.setPixelSize(50, 50);
			settingsDisplay.setPicture(image);
		}
		
		settingsDisplay.setEmail(UserUtil.user.getEmail());
		profileDisplay.getMyplans().fireEvent(new GwtEvent<ClickHandler>() {
			@Override
			public com.google.gwt.event.shared.GwtEvent.Type<ClickHandler> getAssociatedType() {
				return ClickEvent.getType();
			}

			@Override
			protected void dispatch(ClickHandler handler) {
				handler.onClick(null);
			}
		});
	}

	@SuppressWarnings("deprecation")
	private void bind() {
		settingsDisplay.getAddPictureForm().setAction("FileUploadServlet");
		settingsDisplay.getAddPictureForm().setMethod(FormPanel.METHOD_POST);
		settingsDisplay.getAddPictureForm().setEncoding(FormPanel.ENCODING_MULTIPART);
		settingsDisplay.getPictureUpload().setName("pictureUpload");
		settingsDisplay.getPictureUpload().addChangeHandler(new ChangeHandler() {
			
			@Override
			public void onChange(ChangeEvent event) {
				if ("".equals(settingsDisplay.getPictureUpload().getFilename())) {
				} else {
					settingsDisplay.getAddPictureForm().submit();
				}
			}
		});
		settingsDisplay.getAddPictureForm().addSubmitCompleteHandler(new FormPanel.SubmitCompleteHandler() {

			@Override
			public void onSubmitComplete(SubmitCompleteEvent event) {
				Image image = new Image(event.getResults());
				image.setPixelSize(50, 50);
				settingsDisplay.setPicture(image);
			}
		});
		
		
		profileDisplay.getMyplans().addClickHandler(new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent event) {
				profileDisplay.getMyplans().addStyleName("hyperlinkMenu-selected");
				profileDisplay.getSettings().removeStyleName("hyperlinkMenu-selected");
				profileDisplay.getNotifications().removeStyleName("hyperlinkMenu-selected");
				planDisplay.getPlansPanel().clear();
				profileDisplay.getRightPanel().clear();
				profileDisplay.getRightPanel().add(planDisplay.asWidget());
				userServiceAsync.getPlansForUser(UserUtil.user, new AsyncCallback<ArrayList<Plan>>() {
					
					@Override
					public void onSuccess(ArrayList<Plan> result) {
						for (Plan plan : result) {
							final PlanPanel panel = new PlanPanel(plan, true);
							planDisplay.getPlansPanel().add(panel);
							panel.getTitleLabel().addClickHandler(new ClickHandler() {
										
								@Override
								public void onClick(ClickEvent event) {
									eventBus.fireEvent(new ViewPlanEvent(panel.getPlan()));
									}
							});
							panel.getAttendButton().addClickHandler(new ClickHandler() {
										
								@Override
								public void onClick(ClickEvent event) {
									if (panel.isAttending() == true) {
										userServiceAsync.deletePlanForUser(panel.getPlan(), UserUtil.user
												, new AsyncCallback<User>() {
														
											@Override
											public void onSuccess(User result) {
												panel.setAttending(false);
											}
														
											@Override
											public void onFailure(Throwable caught) {
												Window.alert("Could not de-attend this plan");
											}
										});
									} else {
										userServiceAsync.createPlanForUser(panel.getPlan(), UserUtil.user
												, new AsyncCallback<User>() {
														
												@Override
												public void onSuccess(User result) {
													panel.setAttending(true);
												}
														
												@Override
												public void onFailure(Throwable caught) {
													Window.alert("Could not attend this plan");
												}
										});
									}
								}
						});
				}
			}
					
				
				@Override
				public void onFailure(Throwable caught) {
					// TODO Auto-generated method stub
						
				}
			});
			}
		});
		profileDisplay.getSettings().addClickHandler(new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent event) {
				profileDisplay.getSettings().addStyleName("hyperlinkMenu-selected");
				profileDisplay.getMyplans().removeStyleName("hyperlinkMenu-selected");
				profileDisplay.getNotifications().removeStyleName("hyperlinkMenu-selected");
				profileDisplay.getRightPanel().clear();
				profileDisplay.getRightPanel().add(settingsDisplay.asWidget());
			}
		});
		
		settingsDisplay.getSave().addClickHandler(new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent event) {
				User user = UserUtil.user;
				user.setEmail(settingsDisplay.getEmail());
				user.setName(settingsDisplay.getName());
				if (!"".equals(settingsDisplay.getUsername())) {
					user.setUsername(settingsDisplay.getUsername());
				}
				if (!"".equals(settingsDisplay.getPicture().getUrl())) {
					user.setPicture(settingsDisplay.getPicture().getUrl());
				}
				eventBus.fireEvent(new UpdateUserEvent(user));
			}
		});
		profileDisplay.getNotifications().addClickHandler(new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent event) {
				profileDisplay.getNotifications().addStyleName("hyperlinkMenu-selected");
				profileDisplay.getSettings().removeStyleName("hyperlinkMenu-selected");
				profileDisplay.getMyplans().removeStyleName("hyperlinkMenu-selected");
				planDisplay.getPlansPanel().clear();
				profileDisplay.getRightPanel().clear();
				profileDisplay.getRightPanel().add(planDisplay.asWidget());
				userServiceAsync.getSubscriptionsForUser(UserUtil.user, new AsyncCallback<ArrayList<User>>() {
					
					@Override
					public void onSuccess(ArrayList<User> result) {
						for (User user : result) {
							userServiceAsync.getPlansForUser(user, new AsyncCallback<ArrayList<Plan>>() {
							
								@Override
								public void onSuccess(ArrayList<Plan> result) {
									for (Plan plan : result) {
										final PlanPanel panel = new PlanPanel(plan, true);
										planDisplay.getPlansPanel().add(panel);
										panel.getTitleLabel().addClickHandler(new ClickHandler() {
												
											@Override
											public void onClick(ClickEvent event) {
												eventBus.fireEvent(new ViewPlanEvent(panel.getPlan()));
											}
										});
										panel.getAttendButton().addClickHandler(new ClickHandler() {
												
											@Override
											public void onClick(ClickEvent event) {
												if (panel.isAttending() == true) {
													userServiceAsync.deletePlanForUser(panel.getPlan(), UserUtil.user
														, new AsyncCallback<User>() {
																
														@Override
														public void onSuccess(User result) {
															panel.setAttending(false);
														}
																
														@Override
														public void onFailure(Throwable caught) {
															Window.alert("Could not de-attend this plan");
														}
													});
												} else {
													userServiceAsync.createPlanForUser(panel.getPlan(), UserUtil.user
														, new AsyncCallback<User>() {
																
														@Override
														public void onSuccess(User result) {
															panel.setAttending(true);
														}
																
														@Override
														public void onFailure(Throwable caught) {
															Window.alert("Could not attend this plan");
														}
												});
											}
										}
								});
						}
					}
							
						
						@Override
						public void onFailure(Throwable caught) {
							// TODO Auto-generated method stub
								
						}
					});
				}
			}
					
					@Override
					public void onFailure(Throwable caught) {
						// TODO Auto-generated method stub
						
					}
				});
			}
		});
	}

	public void setUsersService(UserServiceAsync userServiceAsync) {
		this.userServiceAsync = userServiceAsync;
	}

	public void setPlanService(PlanServiceAsync planServiceAsync) {
		this.planService = planServiceAsync;
	}

}
